package model;

import org.apache.log4j.Logger;
import utils.EnumType.UnitTime;

/**
 * Classe che contiene le informazioni per la path emulation come delay, jitter,packet loss, 
 * packet duplication e pucket corruption. Ha un solo metodo pubblico ({@link Property#toNetemString()})
 * che restituisce le proprietà da applicare al link secondo la sintassi netem.
 * 
 * @author Dumella De Rosa Gennaro
 *
 */
public class Property {
	
	private static final Logger log = Logger.getLogger(Property.class);
	
	private Period delay;
	private Period jitter;
	
	/**
	 * Packet Loss deve essere espesso in percentuale (max 100) ed il più piccolo valore 
	 * ammissibile è 0.0000000232% 
	 */
	private Double loss;
	/**
	 * Packet Duplication deve essere espesso in percentuale (max 100) ed il più piccolo valore 
	 * ammissibile è 0.0000000232% 
	 */
	private Double duplicate;
	/**
	 * Packet Corruption deve essere espesso in percentuale (max 100) ed il più piccolo valore 
	 * ammissibile è 0.0000000232% 
	 */
	private Double corrupt;

	public Property(Period delay, Period jitter,Double loss, Double duplicate, Double corrupt) {
		
		this.delay = delay;
		this.jitter = jitter;
		this.loss = loss;
		this.duplicate = duplicate;
		this.corrupt = corrupt;
	}
	

	/**
	 * Metodo che restituisce le proprietà di un link utilizzando la sintassi del tool <b>netem</b>. La stringa
	 * restituita va poi utilizzata in combinazione con tc per creare una <b>qdisc</b> che soddisfi le
	 * proprietà in questione.
	 * 
	 * @return una {@link String} che rappresenta le proprietà del link settate secondo la sintassi Netem.
	 */
	public String toNetemString(){
		
		String s = "netem ";
		if( this.delay != null && this.jitter != null)
			s += "delay " + this.delay.toString() + " "
							+ this.jitter.toString() +" ";
		else if ( this.delay != null)
			s += "delay " + this.delay.toString() + " ";
		
		if( this.loss != null && isPercentCorrect(this.loss))
			s += "loss " + this.loss.toString() + "% ";
		
		if( this.duplicate!= null && isPercentCorrect(this.duplicate))
			s += "duplicate " + this.duplicate	.toString() + "% ";
		
		if( this.corrupt != null && isPercentCorrect(this.corrupt))
			s += "corrupt " + this.corrupt.toString() + "% ";
		
		return s;
	}
	
	private boolean isPercentCorrect(Double value){
		if(value.compareTo(new Double(100)) > 0){
			log.warn("Valore inserito errato. La MAX probabilità per packet loss, duplication, e corruption è: 100%");
			return false;
		}else if (value.compareTo(new Double(0.0000000232))<0){
			log.warn("Valore inserito errato. La MIN probabilità per packet loss, duplication, e corruption è: 0.0000000232%");
			return false;
		}else
			return true; 
	}
	
	public static void main(String[] args) {
		Property property = new Property(new Period(UnitTime.second,23),
										new Period(UnitTime.second,50),
										new Double(0.12),new Double(100),new Double(12));
		System.out.println(property.toNetemString());
		
		Property property1 = new Property(new Period(UnitTime.second,23),
				new Period(UnitTime.second,50),
				new Double(0.00000000232),new Double(100),new Double(12));
		System.out.println(property1.toNetemString());
		
		
	}
	
}
